﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Proxies;

namespace Shumisen.Core.Composition.Aop
{
	public class AopProxy : RealProxy
	{
		private readonly Type _interfaceType;

		private readonly object _instance;

		private readonly ReadOnlyCollection<IInterceptor> _interceptors;

		public AopProxy(Type interfaceType, object instance, IEnumerable<IInterceptor> interceptors)
			: base(interfaceType)
		{
			Guard.ArgumentNotNull(interfaceType, "interfaceType");
			Guard.ArgumentNotNull(instance, "instance");
			Guard.ArgumentNotNull(interceptors, "interceptors");
			_interfaceType = interfaceType;
			_instance = instance;
			_interceptors = interceptors.ToReadOnlyCollection();
		}

		public override IMessage Invoke(IMessage message)
		{
			var callMessage = message as IMethodCallMessage;
			var invocation = new Invocation(_interfaceType, _instance, callMessage);
			var interceptorChain = new InterceptorChain(_interceptors);
			interceptorChain.Intercept(invocation);
			return invocation.MethodReturnMessage;
		}
	}
}
